Spring事务常见问题和解决办法

Spring事务配置主要有两种,第一种是XML配置方法前缀,第二种方法是使用注解。很多项目中或多或少都使用过这两种方式,但是我这里推荐优先使用注解的方式。为什么?下面总结说。

列出我在开发、测试中遇到的几个问题(使用XML和开启事务注解)。


    
        
            
            
            
            
            
            
            
            
            
            
            
        
    

1. Connection is read-only

java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:998)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:937)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:872)
	at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1139)

这个错误是因为XML中已经配置了其他方法(即不是那些单词开头的)都是只读的,当你去做增删改的时候就会报错。

解决办法:

1、遵循XML配置的方法前缀。

2、使用@Transactional注解修饰,名称无所谓。

2. UnexpectedRollbackException

org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:720)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:521)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)

这个问题估计在事务方法中出现的频次很高,但是很多人都不清楚为什么出现。原因是因为当前事务方法中去调用其他事务方法(事务的传播性),结果被调用的方法出现异常了,而这个异常又在当前方法中捕获了该异常且没有做处理:

try {
  buss.addOrder(order);
} catch (Exception e) {
  e.printStackTrace();
  //开启事务时不应该捕获异常或者应该抛出
}

解决办法:

1、既然开启了事务就应该让事务回滚,而不是捕获异常(事实上,当使用XML配置事务的时候,是被强迫使用了事务,结果因为没有处理好导致这种错误)!

2、或者把异常抛出,让事务正常回滚(不过这样做的话,下面的方法都不会执行了,既然这样那你开启事务是为了什么?)。

3、被调用的方法再开启一个新的事务,而不是使用当前事务。不过这样做的话需要配合注解来做了——@Transactional(propagation = Propagation.REQUIRES_NEW),但由于XML和注解存在优先级问题不一定生效(取决于顺序配置),同时需要对出现异常的方法进行上面类似的catch。但这么做,无非就是让事务不回滚,那你开启事务的意义何在?

归根结底:正确的解决办法就是既然开启事务就应该让事务去管理,而不是catch!。

3. XML与注解哪个优先级高?

都高,取决于你配置的顺序。即谁放在最下面谁的优先级就高。这个问题,我也搜了一些资料,各有各的说法,有说注解高的也有说XML高的,但最后我在测试过程得出这样的结论。

 

4. 那么,我们使用哪种配置最好呢?

我在这里还是推荐使用注解的方式,原因两点:

1、使用XML的方式有局限性、不灵活,很多时候我们的方法并不需要事务,还有些方法我的命名也不一定是这样的。强制使用事务并不是一个好的做法,使用不当反而会造成其他的问题,特别是对事务理解不透的开发者很难处理好事务问题。

2、微服务、Spring Boot出来后,配置就少了很多,基本上都是基于注解开发,我们没必要把时间都浪费在配置上面。

 

支持我写更多的优质文章,支付宝扫一扫:

Spring事务常见问题和解决办法_第1张图片

你可能感兴趣的:(Java之Spring)