我们在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或连接器本身打开一个事务,导致这些错误。因此,我可以找到针对这些特定问题的各种解决方案过于局部化,这似乎是一个更大的问题。
有没有办法防止这种行为(假设这是实际问题)?
我在这个特定领域的知识很薄,这对我来说是新的。因此,此描述可能缺少重要的细节。请指出我如何改进这个问题,如有必要,我可以添加哪些细节。
答案 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
答案 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)。