与Sybase的Spring事务

时间:2009-11-01 17:54:23

标签: spring serialization sybase transactions

我在我的Web应用程序中使用Spring,底层数据库是Sybase。

我有3个复杂的存储过程要执行。 procs有创建表 drop table 命令来保存临时结果集。

表是在用户数据库空间中创建的,而不是在tempdb空间中创建的。因此,我需要确保序列化来自服务bean的整个服务操作,该服务bean将具有调用存储过程的DAO对象。简单地将服务bean方法作为Spring Transaction,确保在我的情况下解决潜在的并发相关问题?

我注意到的另一件事是,将我的服务方法注释为@Transactional,使sybase数据库抛出一个错误:“创建表命令不能在事务中执行”。这是否意味着Spring使整个数据库操作成为事务? 我真的不清楚这一点,任何解释都会受到欢迎。 这意味着我有一个名为 myproc 的存储过程。 sybase语句为 exec myproc 。例如,这是由服务方法的DAOobject执行的,注释为@Transactional。现在,Spring将数据库操作设为“ begin tran 执行myproc 结束转发“。我的观察似乎暗示了这一点。请解释一下。

并且还解释,如果仅仅是@Transactional的注释,将解决我的并发问题。我实际上不希望我的存储过程的2个实例一次在数据库上运行。

1 个答案:

答案 0 :(得分:0)

你曾经问了很多问题,但我会尽力回答。

  • 将服务标记为@Transactional将其与当前的JTA(Java Transaction API)事务关联(或根据需要创建一个)
  • 根据数据源的配置方式,JDBC连接通常也会与事务关联(登记)
  • 如果连接与JTA事务关联,则在其上执行的任何操作都将在数据库事务中进行。
  • 在Sybase ASE中,您无法在事务中创建(或删除)表。

因此,将您的服务标记为@Transactional将阻止您执行包含create table语句的proc。

然而,无论如何,这都无法解决您所面临的问题。 标记@Transactional,只是意味着它在JTA事务中执行。这意味着它要么提交要么回滚,但它不能防止并发访问。

您有几个选择

  • 如果您知道您的应用程序只能在单个VM上运行,那么您可以将代码标记为serialized。这将确保VM一次只能在该代码中包含1个线程。
  • 您可以在proc中实现并发控制(例如,使用lock table),但这将需要一个事务,这将阻止您在过程中创建一个表。
  • 或者您可以重新设计您的应用程序,而不必跳过所有这些环节。

可能有更简单的方法来实现您正在寻找的结果 - 在proc中创建和删除表,然后尝试阻止对该proc的并发访问不是解决问题的典型方法。