- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试测试异步运行的服务方法 (@Async)。
这是异步方法:
@Async
@Transactional(propagation=Propagation.SUPPORTS, isolation = Isolation.READ_UNCOMMITTED)
public Future<UserPrefs> checkLanguagePreference(long id) {
UserPrefs prefs = prefsDao.retrieveUserPreferences(id);
if(prefs == null || !StringUtils.hasLength(prefs.getLanguage())) {
//Save a new sms-command object
SmsBean command = SmsHelper.buildSmsCommand();
if(! smsDao.checkSameCommandExists(id, command)) {
smsDao.saveSms(id, new SmsBean[] {command}); //Will wait until Lock wait timeout
}
}
return new AsyncResult<UserPrefs>(prefs);
}
这是调用异步方法的测试方法:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(location = "...")
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = false)
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class })
public class MessagingServiceTest {
@Before
public void setUp() {
//Avant tout mettre tout les sms en lu
smsDao.deleteAllSms(1);
sessionFactory.getCurrentSession().flush();
//On vérifie bien qu'il n y a plus de sms
List<SmsBean> list = smsDao.getNewSmsList(1);
assertEquals(0,list.size());
}
@Test
public void checkLanguagePreferenceTest() throws InterruptedException, ExecutionException {
User user = (User) sessionFactory.getCurrentSession().load(User.class, new Long(1));//idUser = 1
// We explicitly blank the preference from db
prefsDao.saveLanguagePref(new UserPrefs("",user));
Future<UserPrefs> prefs = messagingService.checkLanguagePreference(user.getId());
System.out.println("wait completion of async task");
prefs.get();
System.out.println("Async task has finished");
}
}
当执行 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 transactionDEBUG - 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 2DEBUG - 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, 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]]]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 taskDEBUG - Returning cached instance of singleton bean 'txManager'INFO - Ener dans checkLanguagePreference(1)DEBUG - Opening Hibernate SessionDEBUG - Registering Spring transaction synchronization for new Hibernate SessionHibernate: select userprefs0_.id as id2_, userprefs0_.language as language2_, userprefs0_.USER_ID as USER3_2_ from user_prefs userprefs0_ where userprefs0_.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=?INFO - Checking if same sms command already existHibernate: 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, message, origin, sens, status, USER_ID) values (?, ?, ?, ?, ?, ?)DEBUG - Closing Hibernate Session58799 [SimpleAsyncTaskExecutor-1] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 1205, SQLState: 4100058799 [SimpleAsyncTaskExecutor-1] ERROR org.hibernate.util.JDBCExceptionReporter - Lock wait timeout exceeded; try restarting transaction
已解决,但仅供引用,我之前在 MySQL 论坛上创建过一个帖子,解释为什么我从 DBMS 的角度遇到了这个死锁。这是链接(也有很好的解释):
http://forums.mysql.com/read.php?97,409237,409237#msg-409237
最佳答案
由于您的测试被声明为 @Transactional
,因此您有一项大事务分散在 setUp
方法和您的测试方法的执行中。该事务与异步操作中启动的另一个事务发生死锁(异步操作等待主事务获取的锁的释放,主事务等待异步操作的完成)。
您可以通过将主事务分解为多个单独的事务来解决此问题:
@Before
@Transactional // separate transaction for setUp
public void setUp() {
//Avant tout mettre tout les sms en lu
smsDao.deleteAllSms(1);
sessionFactory.getCurrentSession().flush();
//On vérifie bien qu'il n y a plus de sms
List<SmsBean> list = smsDao.getNewSmsList(1);
assertEquals(0,list.size());
}
@Test
@Transactional(propagation = NEVER) // Disable main transaction
public void checkLanguagePreferenceTest() throws InterruptedException, ExecutionException {
// Programmatic transaction for test preparation
User user = tx.execute(new TransactionCallback<User>() {
public User doInTransaction(TransactionStatus status) {
User user = (User) sessionFactory.getCurrentSession().load(User.class, new Long(1));//idUser = 1
// We explicitly blank the preference from db
prefsDao.saveLanguagePref(new UserPrefs("",user));
return user;
}
});
Future<UserPrefs> prefs = messagingService.checkLanguagePreference(user.getId());
System.out.println("wait completion of async task");
prefs.get();
System.out.println("Async task has finished");
}
private TransactionTemplate tx;
@Autowired
public void setPtm(PlatformTransactionManager ptm) {
tx = new TransactionTemplate(ptm);
}
关于java - JUnit 测试对 @transactional @Async 方法的调用导致超出锁等待超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5115554/
我正在尝试使用 Spark 从 Cassandra 读取数据。 DataFrame rdf = sqlContext.read().option("keyspace", "readypulse
这是代码: void i_log_ (int error, const char * file, int line, const char * fmt, ...) { /* Get erro
我必须调试一个严重依赖 Gtk 的程序。问题是由于某些原因,在使用 GtkWindow 对象时开始出现许多运行时警告。问题是,即使 Gtk 提示严重错误,它也不会因这些错误而中止。我没有代码库的更改历
我正在尝试从已有效编译和链接的程序中检索二进制文件。我已经通过 GL_PROGRAM_BINARY_LENGTH 收到了它的长度。该文档说有两个实例可能会发生 GL_INVALID_OPERATION
我有一个托管在 Azure 环境中的服务。我正在使用控制台应用程序使用该服务。这样做时,我得到了异常: "The requested service, 'http://xxxx-d.yyyy.be/S
我有以下代码,它被 SEGV 信号杀死。使用调试器表明它被 main() 中的第一个 sem_init() 杀死。如果我注释掉第一个 sem_init() ,第二个会导致同样的问题。我试图弄清楚是什么
目前我正在编写一个应用程序(目标 iOS 6,启用 ARC),它使用 JSON 进行数据传输,使用核心数据进行持久存储。 JSON 数据由 PHP 脚本通过 json_encode 从 MySQL 数
我对 Xamarin.Forms 还是很陌生。我在出现的主页上有一个非常简单的功能 async public Task BaseAppearing() { if (UserID
这是我的代码的简化版本。 public class MainActivity extends ActionBarActivity { private ArrayList entry = new Arr
我想弄明白为什么我的两个 Java 库很难很好地协同工作。这是场景: 库 1 有一个类 A,其构造函数如下: public A(Object obj) { /* boilerplate */ } 在以
如果网站不需要身份验证,我的代码可以正常工作,如果需要,则在打印“已创建凭据”后会立即出现 EXC_BAD_ACCESS 错误。我不会发布任何内容,并且此代码是直接从文档中复制的 - 知道出了什么问题
我在使用 NSArray 填充 UITableView 时遇到问题。我确信我正在做一些愚蠢的事情,但我无法弄清楚。当我尝试进行简单的计数时,我得到了 EXC_BAD_ACCESS,我知道这是因为我试图
我在 UITableViewCell 上有一个 UITextField,在另一个单元格上有一个按钮。 我单击 UITextField(出现键盘)。 UITextField 调用了以下方法: - (BO
我有一个应用程序出现间歇性崩溃。崩溃日志显示了一个堆栈跟踪,这对我来说很难破译,因此希望其他人看到了这一点并能为我指出正确的方向。 基本上,应用程序在启动时执行反向地理编码请求,以在标签中显示用户的位
我开发了一个 CGImage,当程序使用以下命令将其显示在屏幕上时它工作正常: [output_view.layer performSelectorOnMainThread:@selector(set
我正在使用新的 EncryptedSharedPreferences以谷歌推荐的方式上课: private fun securePrefs(context: Context): SharedPrefe
我有一个中继器,里面有一些控件,其中一个是文本框。我正在尝试使用 jquery 获取文本框,我的代码如下所示: $("#").click(function (event) {}); 但我总是得到 nu
在以下场景中观察到 TTS 初始化错误,太随机了。 已安装 TTS 引擎,存在语音集,并且可以从辅助功能选项中播放示例 tts。 TTS 初始化在之前初始化和播放的同一设备上随机失败。 在不同的设备(
maven pom.xml org.openjdk.jol jol-core 0.10 Java 类: public class MyObjectData { pr
在不担心冲突的情况下,可以使用 MD5 作为哈希值,字符串长度最多为多少? 这可能是通过为特定字符集中的每个可能的字符串生成 MD5 哈希来计算的,长度不断增加,直到哈希第二次出现(冲突)。没有冲突的
我是一名优秀的程序员,十分优秀!