错误原因:事务控制没有做好
原因详细:在spring的事务传播中,错误的将事务的传播特性配置成了
<span style="font-family:Microsoft YaHei;font-size:14px;"><tx:method name="*" propagation="SUPPORTS" /></span>
而Quartz的定时调度是需要启动子线程的。
SessionFactory的getCurrentSession并不能保证在没有当前Session的情况下会自动创建一个新的,这取决于CurrentSessionContext的实现,SessionFactory将调用CurrentSessionContext的currentSession()方法来获得Session。在Spring中,如果我们在没有配置TransactionManager/transactionAdvice并且没有事先调用SessionFactory.openSession()的情况直接调用getCurrentSession(),那么程序将抛出“No Session found for current thread”异常。如果配置了TranactionManager/transactionAdvice并且通过@Transactional或者声明的方式配置的事务边界,那么Spring会在开始事务之前通过AOP的方式为当前线程创建Session,此时调用getCurrentSession()将得到正确结果。
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
表1事务传播行为类型
事务传播行为类型说明
1.PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
2.PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
3.PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
4.PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
5.PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6.PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
7.PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
当使用PROPAGATION_NESTED时,底层的数据源必须基于JDBC 3.0,并且实现者需要支持保存点事务机制。