2009-11-01 63 views
0

我在我的Web应用程序中使用Spring,底层数据库为Sybase。与Sybase的Spring交易

我有3个复杂的存储过程被执行。 的特效,有创建表DROP TABLE命令举行的临时结果集。

这些表在用户分贝空间中创建的,而其在tempdb空间。因此,我面临着需要确保从服务bean(将有DAO对象调用存储过程)的整个服务操作序列化。是否简单地使服务bean方法成为一个Spring Transaction,确保在我的情况下解决潜在的并发相关问题?

,我注意到的是,我的注解服务方法@Transactional,取得了Sybase数据库抛出一个错误另一件事:“CREATE TABLE命令不能在事务内执行。”这是否意味着Spring使整个数据库操作成为事务? 我真的不清楚这一点,任何解释都会受到欢迎。 含义如果我有一个名为myproc的存储过程。 sybase语句将为exec myproc。这就是说,由服务方法中的DAO对象执行,注释为@Transactional。现在,春天在什么使数据库操作“的begin tran 高管在myproc 结束TRAN”。我的观察似乎表明这一点。请解释。

而且也解释了,如果@Transactional的只是注释,能解决我的并发问题。我实际上不希望我的存储过程的两个实例一次在数据库上运行。

+0

创建的表的名称是否以#符号开头?这些名称是固定的,还是以某种方式按照每个请求生成的? – 2009-11-01 22:50:42

+0

这些表不加前缀#,即表在用户数据库空间中创建,而不是在tempdb空间中创建。名称是固定的,尽管表模式是根据请求动态生成的。 – 2009-11-02 15:59:52

+0

DDL(如创建和删除表语句)通常会执行隐式提交,因此您不能将其作为事务性语句的一部分,因此不会出现此错误。 – 2009-11-16 01:20:45

回答

0

你已经问了一些一次性的问题,但我会尽我所能来回答他们。

  • 标记服务,因为它@Transactional与当前的JTA(Java事务API)关联交易(或创建一个如果需要的话)
  • 根据您的数据源是如何配置,JDBC连接通常也被关联(列入交易
  • 如果连接与JTA事务关联,则在其上执行的任何事情都将在数据库事务中发生。
  • 在Sybase ASE中,您不能在事务内创建(或删除)表。

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

但是,这并不能解决你面临的问题。 标记@Transactional,仅表示它在JTA事务中执行。这意味着它要么提交,要么回滚,但它并不防范并发访问。

您有几种选择

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

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