Wie zu konfigurieren, die mehrere Transaktions-Manager mit Feder + DBUnit + JUnit
In einer nussschale
Meine Befehlszeile Java-Anwendung kopiert die Daten aus einer Datenquelle zu einem anderen ohne Verwendung von XA. Ich konfiguriert haben zwei getrennte Datenquellen und würde wie ein JUnit-test, können rollback-Daten auf beiden Datenquellen. Ich benutze DBUnit zum laden von Daten in die "source" - Datenbank, aber ich kann nicht das für den ein rollback ausgeführt. Ich kann das "Ziel" datasource für den ein rollback ausgeführt.
Mein Code
Angesichts dieser config...
<tx:annotation-driven />
<!-- note the default transactionManager name on this one -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceA" />
</bean>
<bean id="transactionManagerTarget" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceB" />
</bean>
und diesen code...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:resources/spring-context.xml",
"classpath:resources/spring-db.xml"})
@Transactional
@TransactionConfiguration(transactionManager = "transactionManagerTarget", defaultRollback = true)
public class MyIntegrationTest {
@Autowired
private MyService service;
@Autowired
@Qualifier("dataSourceA")
private DataSource dataSourceA;
private IDataSet loadedDataSet;
/**
* Required by DbUnit
*/
@Before
public void setUp() throws Exception {
SybaseInsertIdentityOperation.TRUNCATE_TABLE.execute(getConnection(), getDataSet());
SybaseInsertIdentityOperation.INSERT.execute(getConnection(), getDataSet());
}
/**
* Required by DbUnit
*/
protected IDataSet getDataSet() throws Exception {
loadedDataSet = DbUnitHelper.getDataSetFromFile(getConnection(), "TestData.xml");
return loadedDataSet;
}
/**
* Required by DbUnit
*/
protected IDatabaseConnection getConnection() throws Exception{
return new DatabaseConnection(dataSourceA.getConnection());
}
@Test
public void testSomething() {
//service.doCopyStuff();
}
}
Das problem wie ich es sehe, ist, dass @TransactionConfiguration
nur Staaten, die Ziel-Datenquelle damit ein rollback. DBUnit wird übergeben dataSourceA
explizit und nimmt die Standard-Transaktions-manager namens transactionManager
(ich bin mir nicht sicher, wie), die noch nicht gesagt wurde, für den ein rollback ausgeführt.
Frage
Wie kann ich feststellen, sowohl Transaktions-Manager, rollback?
Kann ich mit einer einzigen Transaktion-manager, wenn meine Datenquellen unterstützen keine XA-Transaktionen?
Hinweis: Die Anwendung erfordert keine Transaktions-manager auf dataSourceA, wenn in der Produktion laufen, da es nur read-only. Dieses Problem ist bei meinen tests Klassen nur.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eine mögliche Lösung wäre die Einführung eines Helfer-bean annotiert als
@Transactional("transactionManagerTarget")
und lassen Sie den test kommentiert, als@Transactional("transactionManager")
, Konfiguration sowohl mitdefaultRollback = true
. Dein test müsste dann rufen Sie die Hilfsfunktion bean, die wiederum würde rufen Sie Ihren service-bean im test. Dies sollte dazu führen, dass die Transaktion um Ihren service zurück zu Rollen, dann die Transaktion um DBUnit.Es ist ein bisschen chaotisch, aber.
Andere mögliche Ansätze:
Verwenden Sie die
<qualifier>
element im Ihrem Transaktions-manager-definition.Dann können Sie die Referenz, die Sie verwenden möchten, direkt in die
@Transactional
annotation, d.h.@Before
und@Test
Methoden ausgeführt wird, in der gleichen Transaktion, und ich bin nicht in der Lage, um anzugeben, mehr als ein @Transactional-annotation. In Ihrer Antwort, die ich nicht sehen kann, wie es erzählttransactionManager
zu rollback. Bin ich etwas fehlt? Guter Punkt mit der<qualifier>
obwohl.@Transactional
auf meinem test-Klasse, aber leider wie ich vermutete, die@Test
Methode eine Transaktion startet und die@Before
nicht starten kann, ein weiterer für DBUnit, damit es läuft mit transactionManagerTarget und wird daher nicht rollback der DBUnit-Daten. Ich denke, ich habe alles versucht, ich konnte mit den Anmerkungen, aber kein Glück.Habe ich verwendet, XA-Transaktionen und rollbacks in JUnit-tests mit der open-source-TM Atomikos. Ein nettes feature ist, dass Atomikos ermöglicht die Verwendung von nicht-XA-fähige Datenquellen, um teilnehmen in XA-Transaktionen. Überprüfen Sie diesen link für ein Beispiel: http://www.atomikos.com/Documentation/NonXaDataSource
Auf der anderen Seite, wenn XA ist eine anständige Lösung für Ihre JUnit-Probleme ist eine andere Geschichte. Machen Sie Ihre tests konzentrieren eine Menge auf die Datenbank-Implementierung (Sybase) oder ist es mehr über die Java-Logik? Ich in der Regel setup embedded DBs wie Apache Derby oder HQSQL für JUnit-tests. Dann habe ich nicht zu viel kümmern clean ups, da GC-Griff,:)