“存储过程'xxx'只能在非链式事务模式下运行。”在EJB上下文中从DataSource调用过程时出错

时间:2010-10-06 13:40:26

标签: java jboss ejb-3.0 sybase

我们在Sybase中有一个数据库,我们可以从Java服务器访问它。

使用DriverManager直接通过Sybase驱动程序访问数据库。它工作正常,我们可以调用我们的存储过程。

最近,我们正在迁移到应用程序服务器(在JBoss 5上),现在使用DataSource通过JNDI连接器调用数据库:

Properties ppt = new Properties();
ppt.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
ppt.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
ppt.put("java.naming.provider.url", "jdbc/sybase");

InitialContext ctx = new InitialContext(ppt);
DataSource ds = (DataSource) ctx.lookup(AConfig.getInstance().getDatasourceJndiName());

Connection conn = ds.getConnection();

(使用基本设置配置数据源,来自JBoss example

但是,在此设置中,有几个过程失败,出现此错误:

  

可以运行“存储过程' ** '   仅在非链式交易模式下。“

或此类,对于其他情况(更改失败的命令):

  

不允许使用TRUNCATE TABLE命令   在多语句交易中

从我在互联网上发现的东西看来,它似乎是JBoss或连接器本身打开一个事务,导致这些错误。因此,我可以找到针对这些特定问题的各种解决方案过于局部化,这似乎是一个更大的问题。

有没有办法防止这种行为(假设这是实际问题)?


我在这个特定领域的知识很薄,这对我来说是新的。因此,此描述可能缺少重要的细节。请指出我如何改进这个问题,如有必要,我可以添加哪些细节。

3 个答案:

答案 0 :(得分:5)

显然,在Sybase中,存储过程是以链式或非链式模式运行的。

如果您收到此错误,则表示您的SP已创建为Unchained。此Java行conn.setAutoCommit(false);已转换为“set chained on”。

您可以运行此Sybase SP以列出数据库中所有SP的事务模式:

sp_procxmode

因此,您需要在非链接模式下调用SP并显式使用,创建事务,提交事务和回滚事务。

例如:

insert into publishers 
    values ("9906", null, null, null)
begin transaction
delete from publishers where pub_id = "9906"
rollback transaction

Refer this link.

答案 1 :(得分:1)

这可能有所帮助:http://forum.springsource.org/showthread.php?t=49398,'Holly'似乎解决了问题

答案 2 :(得分:1)

这是不正确的。

当然要看大局。但是还有更大的图景。

应用服务器与否,不是问题。 JBoss与之前的应用程序(Java)服务器中的设置是个问题。您的程序员已正确确保其存储过程执行真正的事务,并且外部实体(任何调用存储过程或应用程序服务器)保护它们免受颠覆。如果他们已经这样做了,那么那些sprocs将从任何应用服务器运行。

“重构”适用于MS世界,在Sybase或Relational世界中根本不需要它。如果您更改sprocs以删除严格的事务控制,业务将受到影响:数据完整性丢失;丧失参照完整性;丢失更新;重复交易;如果您要破坏sprocs,或删除事务控制(而不是“重构”),请注意后果是巨大的。

显然,JBoss默认为AUTOCOMMIT或SET CHAINED ON(因为许多人不编写真正的事务,这些是MS SQL的默认值),并且您以前的Java(app)服务器没有这样做。

其次,与直接连接相比,ODBC非常慢,所以如果你还没有感觉到它,请注意你很快就会知道。数据源没有“实现”,它们只是配置(需要几分钟)。他们使用ODBC或JDBC。它是一个FAT层,在程序和数据库之间放置一个小缓冲区,当然放弃了之前,当你有本机连接时所拥有和享受的所有控件。我已经看到它慢了十二次

第三,没有人在选择它之前检查JBoss(a),Sybase本机连接(而不是通用,面向MS),(b)实施期间和(c)测试期间?

如果你的连接是问题,当然,只需处理连接问题,并实现连接池(Java和Sybase有相应的库),而不是降低应用程序的质量和性能,以及一致性(这是ACID中的C)数据库。

EAServer(Sybase)和WebShpere(IBM)没有这样的问题;他们执行连接池;它们使用ASE的本机连接(不需要ODBC或JDBC)。