java – 如何在Spring中的共享EntityManager上手动启动事务?

前端之家收集整理的这篇文章主要介绍了java – 如何在Spring中的共享EntityManager上手动启动事务?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个LocalContainerEntityManagerfactorybean作为EntityManager实例.

快速删除全表的内容,我想运行以下代码

  1. @Service
  2. public class DatabaseService {
  3. @Autowired
  4. private EntityManager em;
  5.  
  6. @Transactional
  7. public void clear() {
  8. em.createNativeQuery("TRUNCATE TABLE MyTable").executeUpdate();
  9. }
  10. }

结果:

  1. ERROR org.springframework.integration.handler.LoggingHandler: javax.persistence.TransactionrequiredException: Executing an update/delete query
  2. at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71)
  3. at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  4. at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
  5. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  6. at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
  7. at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
  8. at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
  9. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  10. at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
  11. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  12. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  13. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  14. at java.lang.reflect.Method.invoke(Method.java:606)
  15. at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
  16. at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
  17. at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
  18. at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
  19. at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
  20. at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
  21. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
  22. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  23. at java.lang.Thread.run(Thread.java:744)

如果我做这个改变:

  1. public void clear() {
  2. em.getTransaction().begin();
  3. em.createNativeQuery("TRUNCATE TABLE MyTable").executeUpdate();
  4. }

结果:

  1. ERROR org.springframework.integration.handler.LoggingHandler: java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
  2. at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:245)
  3. at com.sun.proxy.$Proxy84.getTransaction(Unknown Source)
  4. at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  5. at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:708)
  6. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  7. at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
  8. at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
  9. at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
  10. at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  11. at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
  12. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  13. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  14. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  15. at java.lang.reflect.Method.invoke(Method.java:606)
  16. at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
  17. at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
  18. at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
  19. at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
  20. at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
  21. at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
  22. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
  23. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  24. at java.lang.Thread.run(Thread.java:744)

我也试过spring-data-jpa,但也失败了:

  1. public interface MyRepository extends CrudRepository<MyEntity,Integer> {
  2. @Query(value = "TRUNCATE TABLE MyTable",nativeQuery = true)
  3. @Modifying
  4. public void clear();
  5. }

那么,如何创建一个事务并在共享的弹簧上下文中运行truncate?

Spring应用程序开始使用:
SpringApplication.run(AppConfig.class,args);有:

  1. @Bean
  2. public JpaTransactionManager transactionManager() {
  3. return new JpaTransactionManager(emf);
  4. }

解决方法

您应该使用TransactionTemplate对象来强制管理事务:
  1. transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  2. @Override
  3. protected void doInTransactionWithoutResult(TransactionStatus status) {
  4. em.createNativeQuery("TRUNCATE TABLE MyTable).executeUpdate();
  5. }
  6. });

要创建TransactionTemplate,只需使用注入的PlatformTransactionManager:

  1. transactionTemplate = new TransactionTemplate(platformTransactionManager);

如果你想使用新的事务调用

  1. transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);

猜你在找的Java相关文章