2010-10-06 29 views
1

Nous avons une base de données dans Sybase, à laquelle nous accédons depuis un serveur Java."La procédure stockée 'xxx' peut être exécutée uniquement en mode transaction déchaînée." erreur lors de l'appel d'une procédure depuis un DataSource, dans un contexte EJB

L'accès à la base de données a été effectué directement via le pilote Sybase, en utilisant DriverManager. Cela fonctionnait correctement, nous étions en mesure d'appeler nos procédures stockées.

Récemment, nous avons une migration vers un serveur d'application (sur JBoss 5), et les appels à la base de données sont maintenant faites par un connecteur JNDI, en utilisant un DataSource:

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(); 

(Le DataSource est configuré en utilisant les paramètres de base, de la JBoss example)

Cependant, dans ce contexte, plusieurs procédures échouent, avec cette erreur:

"Stored procedure '**' may be run only in unchained transaction mode."

ou ce genre, dans d'autres cas (avec le changement de commande à défaut):

TRUNCATE TABLE command not allowed within multi-statement transaction

D'après ce que j'ai trouvé sur Internet, il ressemble à quelque chose dans le JBoss ou le connecteur est l'ouverture d'une transaction elle-même, ce qui provoque ces les erreurs. En tant que tel, les solutions diverses que j'ai pu trouver pour ces problèmes particuliers sont trop localisées, et cela semble être un problème plus important.

Y at-il un moyen d'empêcher ce comportement (en supposant que c'est le problème réel)?


mes connaissances dans ce domaine particulier est assez mince, cela est nouveau pour moi. En tant que tel, il y a probablement des détails importants qui manquent à cette description. S'il vous plaît indiquez moi comment je peux améliorer cette question, quels détails je peux ajouter, si nécessaire.

+0

Qu'est-ce que vous utilisez pour la gestion des transactions? Je suppose que vous lancez un txn à partir d'un bean session sans état? Ce message se produit généralement à cause d'un tiers définissant une propriété auto-commit et/ou le paramètre SET CHAINED sur le DB –

+0

@karianna - la source de données est initialisée dans une servlet init, et les appels après sont faits à partir de beans sans état. Je ne vois pas ce qui peut définir ces propriétés, c'est pourquoi j'ai supposé que c'était un paramètre dans JBoss. Je ne vois aucun autre "tiers" dans ce contexte. – Gnoupi

+0

Je vous recommande fortement de modifier votre code/architecture afin qu'il puisse utiliser la puissance du pool de connexions de JBoss, des sources de données, etc. Le changement de code sera assez petit (c'est toujours une recherche JNDI) et vous pourrez définir si vous utilisez des sources de données XA, locales ou sans transaction à deux phases (vous les définissez dans le fichier * -ds.xml). Voir http://community.jboss.org/wiki/configdatasources pour un point de départ. Vous devrez probablement aussi (par l'intermédiaire des annotations EJB3 que je suppose) vous connecter au gestionnaire Txn de Jboss. –

Répondre

1

Ce n'est pas correct.

Regardez certainement l'image plus grande. Mais il y a encore une image encore plus grande.

serveur d'application ou non, n'est pas le problème. Les réglages dans JBoss par rapport à l'application précédente (Java) est le problème. Vos codeurs ont correctement vérifié que leurs processus stockés exécutent les transactions vraies, et ils sont protégés contre la subversion par des entités externes ( appelant un serveur proc ou app stocké). S'ils l'ont fait, ces sprocs fonctionneront à partir de n'importe quel serveur d'application. "Refactoring" est pour le monde MS, il n'est pas nécessaire du tout dans le monde Sybase ou Relational. Si vous changez les sprocs pour supprimer le contrôle des transactions, l'entreprise va souffrir: perte d'intégrité des données; perte d'intégrité référentielle; mises à jour perdues; dupliquer des transactions; etc. Si vous allez subvertir les sprocs, ou supprimer le contrôle de transaction (par opposition à "refactor"), soyez averti que la conséquence est énorme. De toute évidence, JBoss est défini par défaut sur AUTOCOMMIT ou SET CHAINED ON (car beaucoup de personnes n'écrivent pas de vraies transactions, et ce sont les valeurs par défaut pour MS SQL), et votre précédent serveur Java (app) ne l'a pas fait.Deuxièmement, ODBC est très lent par rapport à une connexion directe, donc si vous ne l'avez pas encore senti, sachez que vous le ferez très bientôt. Les sources de données ne sont pas "implémentées", elles sont simplement configurées (cela prend quelques minutes). Ils utilisent ODBC ou JDBC. C'est une couche FAT entre, et place un petit tampon entre, le programme et la base de données, et bien sûr abandonne tout le contrôle que vous avez eu et apprécié avant, lorsque vous avez eu la connexion native. Je l'ai vu autant que douze fois plus lent. Troisièmement, personne n'a vérifié JBoss (a) avant de le choisir, pour la connectivité native de Sybase (par opposition à générique, orienté MS), (b) pendant la mise en œuvre et (c) pendant le test? Si vos connexions posent problème, assurez-vous de résoudre le problème de connexion et d'implémenter la mise en commun des connexions (Java et Sybase disposent de bibliothèques pour cela), plutôt que de réduire la qualité et les performances de votre application, ainsi que Cohérence (c'est le C dans ACID) de la base de données.

EAServer (Sybase) et WebShpere (IBM) ne rencontrent pas de tels problèmes; ils effectuent la mise en commun des connexions; et ils utilisent une connexion native à ASE (pas d'ODBC ou de JDBC requis).

+0

Merci pour cette description très complète. En fait, nous avons implémenté le regroupement de connexions en Java, fonctionnant correctement, dans l'application existante. Comme je l'ai dit dans ma réponse, nous sommes de retour à l'utiliser, même dans le contexte AS. Il est basé sur les pilotes Sybase, donc nous allons probablement continuer à l'utiliser, car vous suggérez un problème de performance qui se produirait avec cette source de données de JBoss. Votre réponse est la plus descriptive pour ma question, je vais changer la coche "acceptée" pour cela. Merci encore! – Gnoupi

+0

'AUTOCOMMIT' est la même chose que' SET CHAINED OFF' et est le * opposé * de 'SET CHAINED ON' donc votre déclaration" JBoss est soit par défaut AUTOCOMMIT ou SET CHAINED ON' est confuse. soit la terminologie autocommit ("autocommit"/"not autocommit") soit la terminologie chaînée ("chained off"/"chained on" respectivement) –

5

Apparemment, dans Sybase, les procédures stockées sont créées pour s'exécuter en mode chaîné ou non chaîné.

Si vous obtenez cette erreur, cela signifie que votre SP a été créé comme Unchained. Cette ligne Java conn.setAutoCommit(false); est traduite par "set chained on".

Vous pouvez exécuter ce Sybase SP à la liste le mode de transaction de tous vos SP est dans votre DB:

sp_procxmode 

Vous avez donc besoin d'invoquer votre SP sur le mode Unchained et utiliser explicitement, créer transaction, validation de la transaction et transaction de restauration.

Par exemple:

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

Refer this link.