非事务方法也被代理调用,如何避免?
Non transactional methods are also called by proxy, how to avoid that?
我是 spring 的新手,我发现了一个有趣的行为,但不知道如何解决它...我有一个 class 如下:
@组件
public class ScheduleService {
/** The Constant log. */
private static final Logger log = LoggerFactory.getLogger(ScheduleService.class);
/** The schedule repository. */
@Autowired
private ScheduleRepository scheduleRepository;
@Autowired
private PipelineService pipelineService;
private AtomicReference atomic_scheduler = new AtomicReference();
/**
* Instantiates a new schedule service.
*/
public ScheduleService() {
}
/**
* Starts the quarts scheduler instance
*
*/
public synchronized void start() {
....
}
public Scheduler getScheduler() {
start();
return (Scheduler) atomic_scheduler.get();
}
/**
* Creates the schedule.
*
* @param session the session
* @param schedule the Schedule
* @return the Schedule
*/
public Schedule createSchedule(Session session, Schedule schedule) throws Exception {
.......
}
/**
* Gets the Schedule.
*
* @param session the session
* @param id the id
* @return the Schedule
*/
@Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED)
public Schedule getSchedule(Session session, String id) throws Exception {
.......
}
/**
* Gets the Schedule given the Schedule name.
*
* @param session the session
* @param name the name of the Schedule to return
* @return the Schedule
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public Schedule getScheduleByName(Session session, String name) throws Exception {
........
}
/**
*/
public Schedule updateSchedule(Session session, Schedule sch) throws Exception {
.......
}
}
我发现此 class 中的所有方法都由代理调用,但我不知道为什么... APO 代理只应调用 "transactional" 方法吗?我该如何解决这个问题?我希望通过直接调用线程而不通过代理来调用非事务性方法。
谢谢大家的指教。
基本上不可能只有部分方法通过代理调用。
要实现 AOP 行为(在您的情况下为 @Transactional)Spring 必须围绕您的对象构建一个代理,以便它可以拦截对注释方法的调用。为此,Spring 必须在任何地方注入代理而不是你的对象。
所以每个其他对象只知道代理。并且所有调用只能通过代理进行。
如何才能只让交易调用通过代理?这将需要相当多的字节码操作来找到对对象方法的所有调用,而不是根据它们是否是事务性的以某种方式开始重定向它们。还要记住 Spring 不仅支持单例 bean。对于 class 的多个实例,它还必须找出要委托给的 对象。到处注入代理比让 Java 从那里正常工作要容易得多。
如果您需要更多详细信息,您可能需要查看 java.lang.reflect.Proxy
并尝试自己构建代理。这会让您了解 Java 动态代理实际上是如何工作的。 (如果我没记错的话 Spring 也默认使用这个 class 作为它的代理。)
我是 spring 的新手,我发现了一个有趣的行为,但不知道如何解决它...我有一个 class 如下:
@组件 public class ScheduleService {
/** The Constant log. */
private static final Logger log = LoggerFactory.getLogger(ScheduleService.class);
/** The schedule repository. */
@Autowired
private ScheduleRepository scheduleRepository;
@Autowired
private PipelineService pipelineService;
private AtomicReference atomic_scheduler = new AtomicReference();
/**
* Instantiates a new schedule service.
*/
public ScheduleService() {
}
/**
* Starts the quarts scheduler instance
*
*/
public synchronized void start() {
....
}
public Scheduler getScheduler() {
start();
return (Scheduler) atomic_scheduler.get();
}
/**
* Creates the schedule.
*
* @param session the session
* @param schedule the Schedule
* @return the Schedule
*/
public Schedule createSchedule(Session session, Schedule schedule) throws Exception {
....... }
/**
* Gets the Schedule.
*
* @param session the session
* @param id the id
* @return the Schedule
*/
@Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED)
public Schedule getSchedule(Session session, String id) throws Exception {
....... }
/**
* Gets the Schedule given the Schedule name.
*
* @param session the session
* @param name the name of the Schedule to return
* @return the Schedule
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public Schedule getScheduleByName(Session session, String name) throws Exception {
........
}
/**
*/
public Schedule updateSchedule(Session session, Schedule sch) throws Exception {
....... } }
我发现此 class 中的所有方法都由代理调用,但我不知道为什么... APO 代理只应调用 "transactional" 方法吗?我该如何解决这个问题?我希望通过直接调用线程而不通过代理来调用非事务性方法。
谢谢大家的指教。
基本上不可能只有部分方法通过代理调用。
要实现 AOP 行为(在您的情况下为 @Transactional)Spring 必须围绕您的对象构建一个代理,以便它可以拦截对注释方法的调用。为此,Spring 必须在任何地方注入代理而不是你的对象。
所以每个其他对象只知道代理。并且所有调用只能通过代理进行。
如何才能只让交易调用通过代理?这将需要相当多的字节码操作来找到对对象方法的所有调用,而不是根据它们是否是事务性的以某种方式开始重定向它们。还要记住 Spring 不仅支持单例 bean。对于 class 的多个实例,它还必须找出要委托给的 对象。到处注入代理比让 Java 从那里正常工作要容易得多。
如果您需要更多详细信息,您可能需要查看 java.lang.reflect.Proxy
并尝试自己构建代理。这会让您了解 Java 动态代理实际上是如何工作的。 (如果我没记错的话 Spring 也默认使用这个 class 作为它的代理。)