java – JUnit测试对@transactional @Async方法的调用导致超出
发布时间:2020-12-15 01:45:16 所属栏目:大数据 来源:网络整理
导读:我正在尝试测试异步运行的服务方法(@Async). 这是异步方法: @Async@Transactional(propagation=Propagation.SUPPORTS,isolation = Isolation.READ_UNCOMMITTED)public Future 这是调用异步的测试方法: @RunWith(SpringJUnit4ClassRunner.class)@ContextCon
我正在尝试测试异步运行的服务方法(@Async). 这是异步方法:
这是调用异步的测试方法:
当prefs.get()执行时,我有这个错误: Caused by: org.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access: SQLException for SQL [insert into SmsBean (destination,message,origin,sens,status,USER_ID) values (?,?,?)]; SQL state [41000]; error code [1205]; could not insert: Caused by: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3562) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3494) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1960) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2114) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2696) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2105) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2398) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2316) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2301) at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101) at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94) at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57) ... 39 more 这是因为setup方法中的smsDao.deleteAllSms在sms表上持有一个锁. 如何正确避免此锁定超时并能够成功运行我的测试? 谢谢你的帮助. 仅供参考,这是一些控制台输出: DEBUG - Adding transactional method 'checkLanguagePreferenceTest' with attribute: PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED; '' DEBUG - Explicit transaction definition [PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED; ''] found for test context [[TestContext@b76fa testClass = MessagingServiceTest,locations = array['file:src/main/resources/myapp-context.xml','file:src/main/resources/myapp-data.xml','file:src/main/resources/myapp-services.xml'],testInstance = fr.myapp.service.MessagingServiceTest@b01d43,testMethod = checkLanguagePreferenceTest@MessagingServiceTest,testException = [null]]] DEBUG - Retrieved @TransactionConfiguration [@org.springframework.test.context.transaction.Tran sactionConfiguration(defaultRollback=false,transactionManager=txManager)] for test class [class fr.myapp.service.MessagingServiceTest] DEBUG - Retrieved TransactionConfigurationAttributes [[TransactionConfigurationAttributes@5f7d3f transactionManagerName = 'txManager',defaultRollback = false]] for class [class fr.myapp.service.MessagingServiceTest] DEBUG - Returning cached instance of singleton bean 'txManager' DEBUG - Creating new transaction with name [checkLanguagePreferenceTest]: PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED; '' DEBUG - Opened new Session [org.hibernate.impl.SessionImpl@666a53] for Hibernate transaction DEBUG - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@666a53] DEBUG - Changing isolation level of JDBC Connection [org.apache.commons.dbcp.PoolableConnection@1bde3d2] to 2 DEBUG - Exposing Hibernate transaction as JDBC transaction [org.apache.commons.dbcp.PoolableConnection@1bde3d2] DEBUG - No method-level @Rollback override: using default rollback [false] for test context [[TestContext@b76fa testClass = MessagingServiceTest,testException = [null]]] INFO - Began transaction (1): transaction manager [org.springframework.orm.hibernate3.HibernateTransa ctionManager@17753a8]; rollback [false] Hibernate: delete from SmsBean where USER_ID=? Hibernate: select user0_.id as id3_1_,user0_.email as email3_1_,user0_.login as login3_1_,user0_.passwd as passwd3_1_,smsbeans1_.USER_ID as USER7_3_3_,smsbeans1_.id as id3_,smsbeans1_.id as id0_0_,smsbeans1_.destination as destinat2_0_0_,smsbeans1_.message as message0_0_,smsbeans1_.origin as origin0_0_,smsbeans1_.sens as sens0_0_,smsbeans1_.status as status0_0_,smsbeans1_.USER_ID as USER7_0_0_ from User user0_ left outer join SmsBean smsbeans1_ on user0_.id=smsbeans1_.USER_ID where user0_.id=? Hibernate: select user0_.id as id3_,user0_.email as email3_,user0_.login as login3_,user0_.passwd as passwd3_ from User user0_ where user0_.login=? Hibernate: select userprefs0_.id as id2_,userprefs0_.language as language2_,userprefs0_.USER_ID as USER3_2_ from user_prefs userprefs0_ where userprefs0_.USER_ID=? wait completion of async task DEBUG - Returning cached instance of singleton bean 'txManager' INFO - Ener dans checkLanguagePreference(1) DEBUG - Opening Hibernate Session DEBUG - Registering Spring transaction synchronization for new Hibernate Session Hibernate: select userprefs0_.id as id2_,userprefs0_.USER_ID as USER3_2_ from user_prefs userprefs0_ where userprefs0_.USER_ID=? Hibernate: select user0_.id as id3_1_,smsbeans1_.USER_ID as USER7_0_0_ from User user0_ left outer join SmsBean smsbeans1_ on user0_.id=smsbeans1_.USER_ID where user0_.id=? INFO - Checking if same sms command already exist Hibernate: select * from smsbean S where S.USER_ID=? and S.status=? and S.message=? DEBUG - Flushing Hibernate Session on transaction synchronization //Deadlock here : Hibernate: insert into SmsBean (destination,?) DEBUG - Closing Hibernate Session 58799 [SimpleAsyncTaskExecutor-1] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1205,SQLState: 41000 58799 [SimpleAsyncTaskExecutor-1] ERROR org.hibernate.util.JDBCExceptionReporter - Lock wait timeout exceeded; try restarting transaction 已经解决了,但我之前已经创建了一个关于MySQL论坛的一个主题,关于为什么我从DBMS的角度来看这个死锁.这是链接(也解释得很好): http://forums.mysql.com/read.php?97,409237#msg-409237 最佳答案
由于您的测试被声明为@Transactional,因此您有一个大的事务,该事务遍及setUp方法和测试方法的执行.此事务死锁与另一个事务在异步操作中启动(异步操作等待释放主事务获取的锁,主事务等待异步操作完成).
您可以通过将主事务分成几个单独的事务来解决它:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |