1. Quando o mybatis for usado sozinho, use o SQLSession para lidar com transações:
classe pública mybatistxtest {private static sqlSessionFactory SQLSessionFactory; Leitor de leitor estático privado; @BeFeforeClass public static void setupBeFeClass () lança Exceção {try {reader = Resources.getResourCeasReader ("Configuration.xml"); sqlSessionFactory = new SQLSessionFactoryBuilder (). Build (leitor); } finalmente {if (leitor! = null) {reader.close (); }}} @Test public void updateUsertTest () {SQLSession Session = sqlSessionFactory.opensssion (false); // Abra a sessão e a transação começa a tentar {iUserMApper mapper = session.getmapper (iuserMapper.class); Usuário do usuário = novo usuário (9, "transação de teste"); int afetadoCount = mapper.updateUser (usuário); // A instrução COMIT não foi executada devido à exceção subsequente Usuário do usuário = novo usuário (10, "Transação de teste continuamente"); int afetadoCount2 = mapper.updateUser (user2); // A instrução COMIT Int I = 2/0 não é executada devido à exceção subsequente; // A exceção de tempo de execução é acionada session.Commit (); // Envie a sessão, ou seja, a transação commit} finalmente {session.close (); // Feche a sessão e libere recursos}}}
2. Depois de integrar a primavera, use o gerenciamento de transações da Spring:
Uma das principais razões para o uso de Mybatis-Spring é que ele permite que o MYBATIS participe do gerenciamento de transações da primavera. Em vez de criar um novo gerenciador de transações específico para Mybatis, o Mybatis-Spring utiliza o DataSourCetransactionManager que existe na primavera.
Depois que o DataSourCetransActionManager estiver configurado, você pode configurar transações na primavera como normalmente. @Transactional Anotation e configuração do estilo AOP são suportados. Durante o processamento da transação, um objeto SQLSession separado será criado e usado. Quando a transação for concluída, esta sessão será comprometida ou revertida da maneira apropriada.
Depois que a transação for criada, o Mybatis-Spring gerenciará transações transparentemente. Não há necessidade de código extra em seu DAO ou classe de serviço.
1. Configuração padrão
Para ativar o processamento de transações da Spring, basta criar um objeto DataSourCetransactionManager no arquivo de configuração XML da Spring:
<bean id = "transactionManager"> <nome da propriedade = "DataSource" ref = "DataSource"/> </shean>
A fonte de dados especificada geralmente pode ser qualquer fonte de dados JDBC que você use a mola. Isso inclui o pool de conexões e a fonte de dados obtida através da pesquisa JNDI.
Observe que a fonte de dados especificada para o gerenciador de transações deve ser a mesma fonte de dados usada para criar o SQLSessionFactoryBean, caso contrário, o gerenciador de transações não funcionará.
2. Transações de gerenciamento de contêineres
Se você estiver usando um contêiner JEE e deseja que a Spring participe de transações de gerenciamento de contêineres, a mola deve ser configurada usando o JTATRANSACIONGERMANAGER ou sua subclasse especificada por contêineres. A maneira mais conveniente de fazer isso é usar o espaço para nome de transações da Spring:
<tx: jta-transação-manager/>
Nesta configuração, o MYBATIS será o mesmo que outros recursos de transação de primavera configurados por transações de gerenciamento de contêineres. A Spring usará automaticamente quaisquer transações de contêineres existentes, anexando uma SQLSession a ele. Se a transação não for iniciada ou se a transação for necessária, a Spring permitirá que um novo contêiner gerencie transações.
Observe que, se você deseja gerenciar transações usando contêineres e não o gerenciamento de transações da Spring, você deve configurar o SQLSessionFactoryBean para usar o Mybatis ManageDtransaction Factory básico em vez de qualquer outro gerente de transação de primavera:
<bean id = "sqlSessionFactory"> <propriedade name = "DataSource" ref = "DataSource"/> <Nome da propriedade = "TransactionFactoryClass"> <Value> org.apache.ibatis.transaction.managed.managedtransactionFactory "/> </propriedade> </bean>
3. Gerenciamento de transações de programação
O SQLSession da Mybatis fornece um método especificado para lidar com transações programáticas. Mas, ao usar o mybatis-spring, o feijão será injetado usando o SQLSession ou o mapeador gerenciado pela mola. Isso significa que a primavera geralmente lida com transações. Você não pode chamar os métodos sqlSession.Commit (), SQLSession.Rollback () ou SQLSession.Close () no SQLSession gerenciado pela mola. Se você fizer isso, uma UNSupportEdOperationException será lançada. Observe que esses métodos não podem ser acessados ao usar mapeadores injetados. Independentemente de a conexão estar definida como autocomit ou não, a execução do método de dados do SQLSession ou qualquer chamada para o método Mapper fora da transação da mola será automaticamente comprometida. Aqui está um exemplo de uma transação de programação:
DefaultTransactionDefinition def = new DefaultTransactionDefinition (); def.setPropagationBeHavior (transactionDefinition.propagation_required); Transactionstatus status = txManager.getTransaction (def); tente {userMApper.insertUser (usuário); } catch (myException ex) {tiro ex; } txManager.Commit (status);4.@Método transacional:
Crie o arquivo Beans-da-t-t-tx.xml sob o ClassPath e adicione a configuração da transação com base no feijão-da.xml (Série V):
<!-Transaction Manager-> <bean id = "txManager"> <propriedade name = "DataSource" ref = "DataSource" /> < /bean> <!-Driver de anotação da transação, classes e métodos marcados @Transaction será transacional-> <TX: Annotation-Driven Transaction-manysor = "
Categoria de serviço:
@Service ("UserService") Public Class UserService {@AUTOWIRED IUSERMERMAPPER MAPPER; public int BatchUpDateUserswhenexception () {// Usuário não transacional do usuário = novo usuário (9, "antes da exceção"); int afetadoCount = mapper.updateUser (usuário); // execução do usuário bem -sucedido do usuário2 = novo usuário (10, "após a exceção"); int i = 1 /0; // Excepção de tempo de execução int afetagem do AFETFCOUNT2 = Mapper.UpDateUser (User2); // não executado if (afetado aCount == 1 && afetCount2 == 1) {return 1; } retornar 0; } @Transaction Public int txUpDateUserswhenexception () {// Usuário transacional = novo usuário (9, "antes da exceção"); int afetadoCount = mapper.updateUser (usuário); // reversão devido à exceção subsequente Usuário2 = novo usuário (10, "após a exceção"); int i = 1 /0; // joga uma exceção de tempo de execução e a reversão da transação int afetadaCount2 = mappper.updateUser (user2); // não executado if (afetado aCount == 1 && afetCount2 == 1) {return 1; } retornar 0; }}Na classe de teste:
@Runwith (springjunit4classrunner.class) @ContextConfiguration (Localizações = {"ClassPath: Beans-da-tx.xml"}) classe pública SpringIntegratextest {@Resource UserService Uservice; @Test public void updateUserSexceptEst () {userservice.batchupdateUserswhenexception (); } @Test public void txupDateUserSceptionTest () {userservice.txupdateUserswhenexception (); }}
5. Método transactionTemplate
Adicione os feijões-da-tx.xml:
<bean id = "txtemplate"> <construtor-arg type = "org.springframework.transaction.platformtransactionManager" ref = "transactionManager" /> < /bean>
Participe da classe UserService:
@AUTOWIRED (requerir = false) transactionTemplate txtemplate; public int txUpDateUserswheNexceptionViatTemplate () {int retVal = txtemplate.execute (new TransactionCallback <Teger> () {@Override public integro dointransaction (transactionStatus status) {// Operação de transação User = Novo User (9, "Antes da exceção"); Usuário subsequente de exceção 2 = Usuário (Após a exceção "); return retornVal; }Adicione à classe Springintegratetxtest:
@Test public void updateUserswhexceptionvitxtemplateTest () {userservice.txupdateUserswhenexceptionvittxplate (); //}NOTA: Não é possível capturar exceção ou tempo de execução sem jogar:
@Transaction Public int txUpDateUserswhenexceptionAndCatch () {// Operação transacional, mas a estrutura periférica não pode pegar a exceção e enviá -la se a execução estiver correta. tente {usuário do usuário = novo usuário (9, "antes da exceção"); int afetadoCount = mapper.updateUser (usuário); // A execução foi bem -sucedida usuário do usuário2 = novo usuário (10, "após a exceção"); int i = 1 /0; // Excepção de tempo de execução int afetagem do AFETFCOUNT2 = Mapper.UpDateUser (User2); // não executado if (afetado aCount == 1 && afetCount2 == 1) {return 1; }} catch (Exceção e) {// Todas as exceções são capturadas sem jogar e.printStackTrace (); } retornar 0; }