线程池中如何使用Spring事务

下面的代码在线程池中调用deviceInfoService服务的updateDeviceInfo方法,接着抛出空指针异常,然而数据没有回滚。

public void testUpdate() {
	executor.execute(new Runnable() {
		@Override
		public void run() {
			DeviceInfo deviceInfo = new DeviceInfo();
			deviceInfo.setDeviceId(95352L);
			deviceInfo.setRoomName("我的小窝");
			deviceInfoService.updateDeviceInfo(deviceInfo);
			throw new NullPointerException();
		}
	});
}

下面想自己手动进行事务提交,但是通过注入PlatformTransactionManager的方式获取事务,会抛出异常

Exception in thread "taskExecutor-1" org.springframework.transaction.IllegalTransactionStateException: Transaction is already completed - do not call commit or rollback more than once per transaction
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:821)
	at com.clife.business.csleep.hotel.device.service.DeviceInfoServiceImpl$2.run(DeviceInfoServiceImpl.java:532)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:744)
@Resource
private PlatformTransactionManager txManager;
public void testUpdate() {
	executor.execute(new Runnable() {
		@Override
		public void run() {
			DefaultTransactionDefinition def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
			TransactionStatus status = txManager.getTransaction(def);
			try {
				DeviceInfo deviceInfo = new DeviceInfo();
				deviceInfo.setDeviceId(95352L);
				deviceInfo.setRoomName("我的小窝");
				deviceInfoService.updateDeviceInfo(deviceInfo);
				// 提交事务
				txManager.commit(status);
				throw new NullPointerException();
			} catch (Exception e) {
				// 回滚事务
				txManager.rollback(status);
			}
		}
	});
}

下面的代码在线程池中获取PlatformTransactionManager实例,这种方式是可行的

public void testUpdate() {
	executor.execute(new Runnable() {
		@Override
		public void run() {

			DefaultTransactionDefinition def = new DefaultTransactionDefinition();
			def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
			PlatformTransactionManager txManager = ContextLoader.getCurrentWebApplicationContext().getBean(PlatformTransactionManager.class);
			TransactionStatus status = txManager.getTransaction(def);

			try {
				DeviceInfo deviceInfo = new DeviceInfo();
				deviceInfo.setDeviceId(95352L);
				deviceInfo.setRoomName("我的小窝");
				deviceInfoService.updateDeviceInfo(deviceInfo);
				// 提交事务
				txManager.commit(status);
				throw new NullPointerException();
			} catch (Exception e) {
				// 回滚事务
				txManager.rollback(status);
			}
			
		}
	});
}

你可能感兴趣的:(Java,并发编程,springmvc,spring)