多个共享数据库休眠事务



我有一个基于spring的tomcat服务。我使用基于注释的hibernate映射,并且我有多个分片数据库。Student说,所有的分片数据库都有相同的表。我想使用@Transactional注释在它们上实现事务。

@Autowired
List<SessionFactory> sessionFactoryList;
@Transactional
public insertStudentBatch(List<Student> students) {
}

现在我想插入整个批次。如果出现任何错误,我希望所有错误都回滚。最好的方法是什么?我可以像@Transactional("txManager1", "txManager2")一样写多个TransactionManager限定符吗?

否,不幸的是,spring@Transactional注释是特定于单个事务管理器的,并且不会按照您所描述的愿望进行操作。

在我看来,你可能想要的是一个用于2PC提交的JTA事务,在这里你基本上启动一个主JTA事务然后对于每个SessionFactory,你为你的碎片调用每个特定的事务管理器并执行你的操作。

 @Service
 public class StudentBatchServiceImpl implements StudentBatchService {
   @Autowired List<StudentService> studentServices;
   @Transactional(value = "jtaTransactionManager")
   public void storeStudents(List<Student> students) {
     for(StudentService service : studentServices) 
       service.storeStudents(students);
   }
 }
 public interface StudentService {
   void storeStudents(List<Student> students);
 }
 public abstract AbstractStudentServiceImpl implements StudentService {
   protected void storeStudents(EntityManager em, List<Student> students) {
     for(Student student : students) {
       em.persist(student);
     }
   }
 }
 @Service
 public class Shard1StudentServiceImpl extends AbstractStudentServiceImpl {
   @PersistenceContext(name = "shard1")
   private EntityManager entityManager;
   @Override
   @Transactional(value = "shard1TransactionManager")
   public void storeStudents(List<Student> students) {
     storeStudents(entityManager, students);
   }
 }

在没有使用JTA的2PC提交设置的情况下,可能还有一些其他方法可以处理此问题,但主要是在容器管理的事务中(如JBoss、WebLogic等);这将是一种方法。

作为一个侧栏,如果你已经走上了春天的道路,我建议你看看spring-batch。对于过多的用例,它为类似批处理的操作提供了一个不错的基线。我上面描述的是spring-batch中一个案例的拙劣实现。

更新

如果您想避免创建多个带有注释详细信息的shard类实现,可以使用XML配置并使用单个类实现:

 <bean id="shard1" class="default.ShardStudentServiceImpl">
   <property name="entityManager" ref="shard1EntityManager" />
   <property name="transactionManager" ref="shard1TransactionManager" />
 </bean>

这里唯一的区别是,您必须用XML定义您的25个shard,然后您必须编写自己的代码来启动、提交和管理ShardStudentServiceImpl类中的事务。

在上面显示的最终实现中,使用抽象基类和注释,我的更新到达了相同的目的地。事实上,如果您查看spring-batch,您会注意到它们的批处理配置遵循类似的前提,将实体管理器和事务管理器指定为单个类的输入属性。

相关内容

  • 没有找到相关文章

最新更新