Предисловие
В этой статье в основном записывается, как Spring поддерживает вещи, и как она может просто реализовать функции базы данных, когда Spring объединяет Mybatis. Я не скажу много об этом ниже, давайте посмотрим на подробное введение вместе.
CASE1: Вещи поддерживают ситуацию в двух таблицах
Сначала подготовьте две таблицы, одну пользовательскую таблицу и одну сюжетную таблицу, структура следующая
Создать таблицу `user` (` `id` int (11) unsigned not null auto_increment,` name` varchar (20) не null default '' comment ray username ', `pwd` varchar (26) не nul `newchated` varchar (13) не null default '0', первичный ключ (` id`), ключ «name» (`name`)) ingine = innodb default charset = utf8mb4; создать таблицу` story` (`ind` int (11) unsigned not null auto_increm varchar(20) NOT NULL DEFAULT '' COMMENT 'Author', `title` varchar(26) NOT NULL DEFAULT '' COMMENT 'password', `story` text COMMENT 'Story content', `isDeleted` tinyint(1) NOT NULL DEFAULT '0', `created` varchar(13) NOT NULL DEFAULT '0', `updated` varchar(13) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `userId` (` userId`)) ingine = innodb default charset = utf8mb4;
Наша ситуация заключается в том, что когда пользователь изменяет имя, имена обеих таблиц должны быть изменены вместе, а несоответствия не допускаются.
case2: поддержка одной таблицы
Передача денег, один пользователь сокращает деньги, другой пользователь увеличивает деньги
CREATE TABLE `money` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '' COMMENT 'Username', `money` int(26) NOT NULL DEFAULT '0' COMMENT 'money', `isDeleted` tinyint(1) NOT NULL DEFAULT '0', `created` varchar(13) NOT NULL DEFAULT '0', `updated` varchar (13) не null default '0', первичный ключ (`id`), клавиша` name` (`name`)) engine = innodb default charset = utf8mb4;
По сравнению с вышеупомянутым случаем, это проще. Следующие примеры в основном объясняются на основе этого. Что касается Case1, он остается расширенным.
Во -первых, реализовать соответствующие DAO и сущность
@Datapublic class MoneyEntity реализует Serializable {Private Static Long Long SerialVersionUID = -7074788842783160025L; частный INT ID; Приватное название строки; частные деньги; частный INTSELELED; частный int создан; private int vonduvation;} public interface moneydao {moneyentity QueryMoney (@param ("id") int userid); // Добавить деньги, когда отрицательно, это означает сокращение денег int incrementmoney (@param ("id") int userid, @param ("addmoney") int addmoney);}Соответствующий файл Mapper
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Mapper public "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> mapper.org/dtd/mybatis-3-mapper.dtd"> mapper. namespace = "com.git.hui.demo.mybatis.mapper.moneydao"> <sql id = "moneyentity"> id, `name`,` money`, `isdeleted`,` created`, `indated` </sql> <selet id =" querymoney ' resultType = "com.git.hui.demo.mybatis.entity.moneyentity"> select <include refid = "moneyentity"/> от денег, где id =#{id} </select> <Обновление идентификатор = "INGRENTMoney"> Обновление Money Set Money = Money +#{addMoney}, где id =#{id} </update> </update> </update> </update> </update> </update> </update> </update> </update> </update> </update> </update> </update> </update> </update>Соответствующая конфигурация источника данных подключения Mybatis
<Bean> <name = name = "locations"> <dall> classpath*: jdbc.properties </value> </property> </bean> <bean id = "dataSource" init-method = "init" dissome-method = "close"> <property name = "DriverClassname" value = "$ {Driver}"/> <name = "url" value "value ="/"ral" value = "/" ral "value ="/"/" ral "value"/"/ral"/"/" ral "value"/"/"/"ral" name="username" value="${username}"/> <property name="password" value="${password}"/> <property name="filters" value="stat"/> <property name="maxActive" value="20"/> <property name="initialSize" value="1"/> <property name="maxWait" value="60000"/> <property name="minIdle" value = "1"/> <name = "timeBeneEvictionRunSmillis" value = "60000"/> <name = "minevictableIdletImelis" value = "300000"/> <name = "validationQuery" value = "select 'x'/> <name =" testwhileIdle "valietQuer name = "testonBorrow" value = "false"/> <name = "testonRepurn" value = "false"/> <name = "poolpreparedStatements" value = "true"/> <name = "maxpoolpreparedStatementPerconcectionsize" value = "50"/> </> bean> <bean -id = "sqlessecsecectionfectize" value = "50"/> </bean> <bean id = "sqlessessionfactoceize"> ". ref = "dataSource"/> <!-Укажите файл Mapper-> <name = "mapperlocations" value = "classpath*: mapper/*. xml"/> </bean> <!-Укажите сканирование dao-> <bean> <propatore = "basepackage" value = "com.git.hui.demo.mybatis"/> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </> </>Благодаря онлайн -запросу есть четыре способа управления весенними вещами. Вот демонстрации один за другим, как играть в каждый метод, а затем посмотреть, как выбрать в реальном проекте
Управление программированием, которое реализует вещью управление несколькими операциями БД через TransactionTemplate
а Выполнение
Затем наш трансферный случай может быть реализован следующим образом
@RepositoryPublic Class CodedEmo1 {@autowired Private MoneyDao MoneyDao; @Autowired Private TransactionTemplate TransactionTemplate; / ** * Transfer * * @param inuserid * @param Outuserid * @param paymoney * @param status 0 указывает на нормальную передачу, 1 указывает на то, что исключение отменяется внутри, 2 указывает на новую ветку, измените деньги Inuserid + 200, 3 указывает на новую нить, модифицируйте деньги Outuserid + 200 */ public in in inUserId, окончательный, финал, финал, финал, окончательный, окончательный, финал, финал, финал, финал, финал, окончательный, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал. Статус) {transactionTemplate.execute (new TransactionCallbackWithOUtresult () {Protected void doIntransactionWithoutresult (TransactionStatus TransactionStatus) {MoneyEntity Entity = MoneyDao.Querymone moneydao.incrementmoney (Overserid, -paymoney); } // Следующие приведены все связанные тестовые примеры Private void Testcase (Final Int Inuserid, Final int Outserid, Final Int Status) {if (status == 1) {бросить новый allosalargumentException («Исключение передачи !!!»); } else if (status == 2) {addmoney (inuserid); try {thread.sleep (3000); } catch (прерванное искусство e) {e.printstacktrace (); }} else if (status == 3) {addMoney (OverserId); try {thread.sleep (3000); } catch (прерванное искусство e) {e.printstacktrace (); }}} public void addMoney (final int userId) {System.out.printf ("Внутренняя addmoney:" + system.currenttimemillis ()); Новый поток (new Runnable () {public void run () {moneydao.incrementmoney (userId, 200); System.out.println ("Sub -Medify успех! Теперь:" + System.currentTimeMillis ());}}). start (); }}В основном посмотрите на приведенный выше метод преобразования. Инкапсуляция вещей реализуется через TransactionTemplate внутри. Есть три операции ДБ внутри, один запрос и два обновления. Конкретный анализ будет объяснен позже.
Приведенный выше код относительно прост. Единственное, на что вам нужно обратить внимание, - это то, как определяется боб TransactionTemplate. Если вы не вставляете файл XML и предыдущие, просто вставьте код клавиши. Одним из них является TransactionManager, созданный на основе данных данных, а другой - TransactionTemplate, созданный на основе TransactionManager.
<!-Программирование вещей-> <bean id = "transactionManager"> <name = "dataSource" ref = "dataSource"/> </bean> <bean id = "transactiontemplate"> <name = "transactionManager" ref = "TransactionManager"/> </bean>
беременный Тестовые случаи
Нормальная демонстрационная ситуация, демонстрация не имеет исключений, и ситуация с параллелизмом не учитывается
@Runwith (springjunit4classrunner.class) @contextconfiguration ({"classpath*: spring/service.xml", "classpath*: test-datasource1.xml"}) открытый класс codedemo1test {@autowworired Cdedemo1 CodeDemo1; @Autowired private moneydao moneydao; @Test public void testtransfor () {System.out.println ("----------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); codedemo1.transfor (1, 2, 10, 0); System.out.println ("-----------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); }}Вывод заключается в следующем, нет проблем с деньгами обоих счетов
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10000
ID: 2 деньги = 50000
Передача завершена! Сейчас: 1526130394266
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Аномалия происходит в процессе передачи, особенно когда переводчик вычитал деньги, а получатель не получил деньги, то есть ситуация, когда статус в деле составляет 1.
// внутреннее исключение, бросающее @testpublic void testtransforexception () {system.out.println ("--------------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); try {codedemo1.transfor (1, 2, 10, 1); } catch (Exception e) {e.printstackTrace (); } System.out.println ("---------------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ());}В связи с этим мы надеемся вернуть деньги от переводчика и вывести их следующим образом. Мы обнаружили, что ни один из денег не изменился.
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
java.lang.illegalargumentException: Transfer Exception !!!
... // Опустить информацию об исключении
ID: 2 деньги = 49990
Когда статус составляет 2, это означает, что между деньгами переводчика были вычтены, и деньги получателя не были получены, кто -то передал 200 к получателю. В настоящее время, согласно механизму блокировки MySQL, передача другого человека должна быть немедленно получена (поскольку счета получателя не заблокирована), и с суммой не должно быть никаких проблем.
Результат вывода заключается в следующем:
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
## справа примечание: во время процесса перевода деньги были сразу депонированы, а деньги были добавлены внутри, не заблокированы: 1526130827480
Суб -изменение успеха! Сейчас: 1526130827500
## Перевод завершен после экономии денег! Сейчас: 1526130830488
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10220
ID: 2 деньги = 49980
Когда статус составляет 3, это означает, что деньги переводчика были вычтены, а деньги получателя не были получены, и кто -то передал 200 в переводчик. В настоящее время, поскольку добавлены записи и записи передачи и записи, он может только дождаться передачи, чтобы отправить передачу в успех до успеха +200. Конечно, окончательная сумма также должна быть такой же.
Результат вывода выглядит следующим образом
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10220
ID: 2 деньги = 49980
## справа - примечание: я сэкономил деньги внутри, но это не удалось немедленно сразу
## только после завершения передачи он сразу же успешен. Обратите внимание на добавление денег в две временные метки: 1526131101046
Передача завершена! Сейчас: 1526131104051
Суб -изменение успеха! Сейчас: 1526131104053
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10230
ID: 2 деньги = 50170
в Краткое содержание
До сих пор программирование было продемонстрировано в примере. Из приведенного выше процесса это дает людям то же чувство, что и написание вещей, связанных с SQL.
Начать транзакцию;
- Это логика внутри метода TransactionTemplate#Execute
- то есть набор SQL, который требует управления вещамисовершить;
Следующие три - это декларативное управление вещью, которая менее используется, потому что каждый класс управления вещью необходимо добавить в транзакционную ProxyFactoryBean
а Выполнение
В дополнение к убийству TransactionTemplate и удалению внутренней логики SQL по сравнению с предыдущей, я обнаружил, что в основном нет разницы.
Public Class FactoryBeandemo2 {@Autowired Private MoneyDao MoneyDao; / ** * Transfer * * @param inuserid * @param Outuserid * @param paymoney * @param status 0 указывает на нормальную передачу, 1 указывает на то, что исключение было добавлено внутри, 2 указывает на новую ветку, измените деньги Inuserid + 200, 3 указывает на новую нить, изменить деньги Outuserid + 200 */ public void transfer (final in -inuserId, окончательный intuse, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал, финал. Статус) {moneyEntity entity = moneydao.querymoney (Outserid); if (entity.getmoney ()> paymoney) {// Вы можете перевести деньги // сократить деньги первые деньги. Testcase (Inuserid, Overserid, статус); // Добавить деньги в moneydao.incrementmoney (inuserid, paymoney); System.out.println («Передача завершена! Теперь:» + System.currentTimeMillis ()); }} private void testcase (final int inuserid, final int Outserid, final int status) {if (status == 1) {throw new allogalArgumentException ("transfer Exception !!!); } else if (status == 2) {addmoney (inuserid); try {thread.sleep (3000); } catch (прерванное искусство e) {e.printstacktrace (); }} else if (status == 3) {addMoney (OverserId); try {thread.sleep (3000); } catch (прерванное искусство e) {e.printstacktrace (); }}} public void addMoney (final int userId) {System.out.println («Внутреннее добавление денег:» + system.currenttimemilsis ()); Новый поток (new Runnable () {public void run () {moneydao.incrementmoney (userId, 200); System.out.println ("Sub -Medify успех! Теперь:" + System.currentTimeMillis ());}}). start (); }}Ключевым моментом является то, что нам нужно настроить транзакционную программу. Мы знаем, что BeanFactory - это средство для нас, чтобы создать боб сами. Связанная конфигурация XML выглядит следующим образом
<!-Программирование вещей-> <bean id = "transactionManager"> <name = "dataSource" ref = "dataSource"/> </bean> <bean id = "factorybeandemo2"/> <!-Конфигурируйте прокси для бизнес-слоя-> <bean id = "factorybeandemoproxy"> <! ref = "factorybeandemo2" /> <!-Inject The Transaction Manager-> <name = "transactionManager" ref = "TransactionManager" /> <!-инъекция свойства транзакции-> <Название свойства = "TransactionAttributes"> <Props> <! Исключения возвращают транзакции* +Исключение: какие исключения не откатаются назад транзакциями-> <!-Этот ключ соответствует методам в целевом классе-> <prop key = "transfor"> Propagation_Required </prop> <!-<prop key = "transfer"> propagation_required, readonly </prop>-> <!-<prop quee = "> transforte '> propagation_re, readonly </prop>-> <! <prop key = "transfer"> propagation_required,+java.lang.arithmeticexception </prop> -> </props> </property> </bean>
Благодаря вышеуказанной конфигурации мы можем примерно понять, что TransactionProxyFactoryBean создает прокси -класс FactoryBeandemo2. Этот класс прокси инкапсулирует логику, связанную с хорошими вещами, которые можно рассматривать как простую общую абстракцию предыдущего программирования.
беременный Тест
Тестовый код в основном такой же, как и раньше. Единственное отличие состоит в том, что мы должны использовать бон, генерируемый BeanFactory выше, а не непосредственно с использованием FactoryBeandemo2
Нормальный демонстрационный случай:
@Runwith (springjunit4classrunner.class) @contextconfiguration ({"classpath*: spring/service.xml", "classpath*: test-datasource2.xml"}) открытый класс FactoryBeandemo1test {@Resource (name = "factoryBeanDemopRoxy") factory2BeanMemy.AneAneMopRey2BeanDemO2BeanMORPORY2 @Autowired private moneydao moneydao; @Test public void testtransfor () {System.out.println ("--------------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); FactoryBeandemo2.transfor (1, 2, 10, 0); System.out.println ("------------------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); }}Выход
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10000
ID: 2 деньги = 50000
Передача завершена! Сейчас: 1526132058886
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Если статус равен 1, а внутреннее исключение не так, мы надеемся, что с деньгами не будет никаких проблем.
@Testpublic void testtransforexception () {System.out.println ("---------------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); try {factorybeandemo2.transfor (1, 2, 10, 1); } catch (Exception e) {System.out.println (e.getMessage ()) ;; } System.out.println ("--------------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ());}Выход
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Передавать аномалия !!!
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Когда статус равен 2, результат анализа должен быть таким же, как и выше, а вывод следующим образом
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49950
Внутренние деньги: 1526133325376
Суб -изменение успеха! Сейчас: 1526133325387
Передача завершена! Сейчас: 1526133328381
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10220
ID: 2 деньги = 49940
Когда статус 3, вывод
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10220
ID: 2 деньги = 49940
Внутренние деньги: 1526133373466
Передача завершена! Сейчас: 1526133376476
Суб -изменение успеха! Сейчас: 1526133376480
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10230
ID: 2 деньги = 50130
в Краткое содержание
Идея TransactionProxyFactoryBean заключается в использовании прокси -режима для реализации управления вещами, генерировать класс прокси, перехват целевых методов и инкапсулировать набор операций SQL в вещи; По сравнению с жестким кодом он неинвазивный и поддерживает гибкие методы конфигурации.
Недостатки также очевидны, каждый должен быть настроен, что довольно сложно
Весна имеет две основные характеристики: МОК и AOP. Для таких вещей, можем ли мы использовать AOP, чтобы сделать это?
Для методов, которые необходимо включить, перехватить, запустить вещи перед выполнением, отправьте вещи после выполнения и откатитесь, когда происходит исключение.
С этой точки зрения, это кажется довольно многообещающим, и следующие две позы воспроизводится таким образом, поэтому необходима зависимость аспекта.
<Depective> <groupid> org.aspectj </GroupId> <artifactId> AspectJweaver </artifactId> <sersion> 1.8.7 </version> </vehing>
а Выполнение
Класс Java точно такой же, как и второй тип, и только XML изменяется
<!-Сначала добавьте пространство имен-> xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalocation = " http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"<!- Соответствующее уведомление и конфигурация секции-> <tx: usd = "txadvice" transaction-manager = "Transaction Manager"> <tx: usd = "txadvice". Распространение: Поведение распространения транзакций. Изоляция: Изоляция транзакции. Конфигурационная точка вырезана-> <aop: pointcut Expression = "execution (* com.git.hui.demo.mybatis.repository.transaction.xmldemo3.* (..)" id = "pointcut1"/> <!-Раздел конфигурации-> <aop: Advisor Asse-ref = "txadvice" pointcut-ref = "pointcut1"/> </aop: config>
Соблюдайте приведенную выше конфигурацию и подумайте о втором методе. Идея почти такая же, но этот метод, очевидно, более общий. Через раздел и точку резки можно уменьшить большое количество конфигураций.
беременный Тест
@Runwith (springjunit4classrunner.class) @contextconfiguration ({"classpath*: spring/service.xml", "classpath*: test-datasource3.xml"}) открытый класс xmlbeantest {@autowired private xmldemo3 xmldemo; @Autowired private moneydao moneydao; @Test public void testtransfor () {System.out.println ("---------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); xmldemo.transfor (1, 2, 10, 0); System.out.println ("------------------------"); System.out.println ("id: 1 money =" + moneydao.querymoney (1) .getmoney ()); System.out.println ("id: 2 money =" + moneydao.querymoney (2) .getmoney ()); }}Этот тест ничем не отличается от общего метода написания и проще, чем метод инъекции второго заводского боя
Нормальный выход
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10000
ID: 2 деньги = 50000
Передача завершена! Сейчас: 1526135301273
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Статус = 1 Когда происходит исключение, выход
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Передавать аномалия !!!
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Статус = 2 Сценарий экономии денег во время процесса передачи, результат соответствует предыдущим ожиданиям.
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10010
ID: 2 деньги = 49990
Внутренние деньги: 1526135438403
Суб -изменение успеха! Сейчас: 1526135438421
Передача завершена! Сейчас: 15261354441410
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10220
ID: 2 деньги = 49980
Вывод статуса = 3 согласуется с предыдущими ожиданиями
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10220
ID: 2 деньги = 49980
Внутренние деньги: 1526135464341
Передача завершена! Сейчас: 1526135467349
Суб -изменение успеха! Сейчас: 1526135467352
----------------------------------------------------------------------------------------------------------------------------
ID: 1 деньги = 10230
ID: 2 деньги = 50170
Это должно устранить XML и использовать аннотации для этого, то есть заменить конфигурацию в предыдущем XML на @Transactional Annotation.
а Выполнение
@RepositoryPublic Class AnnoDemo4 {@autowired Private MoneyDao MoneyDao; /**! readonly: только для чтения* Rollbackfor: какие исключения произошли Norollbackfor: какие исключения не произошли, чтобы не откатить* RollbackforClassName Rollback в соответствии с названием класса исключений*/ @Transactional (Propagation = Propagation. {MoneyEntity entity = moneydao.querymoney (Overserid); if (entity.getmoney ()> paymoney) {// Вы можете перевести деньги // сократить деньги первые деньги. Testcase (Inuserid, Overserid, статус); // Добавить деньги в moneydao.incrementmoney (inuserid, paymoney); System.out.println («Передача завершена! Теперь:» + System.currentTimeMillis ()); }} private void testcase (final int inuserid, final int Outserid, final int status) {if (status == 1) {throw new allogalArgumentException ("transfer Exception !!!); } else if (status == 2) {addmoney (inuserid); try {thread.sleep (3000); } catch (прерванное искусство e) {e.printstacktrace (); }} else if (status == 3) {addMoney (OverserId); try {thread.sleep (3000); } catch (прерванное искусство e) {e.printstacktrace (); }}} private void AddMoney (final int userId) {System.out.println ("Inside Add Money:" + System.currentTimeMiLlis ()); Новый поток (new Runnable () {public void run () {moneydao.incrementmoney (userId, 200); System.out.println ("Sub -Medify успех! Теперь:" + System.currentTimeMillis ());}}). start (); }}Следовательно, необходимо настроить его в XML, чтобы включить аннотацию вещей
<!-Программирование вещей-> <bean id = "transactionManager"> <name = "dataSource" ref = "dataSource"/> </bean> <tx: аннотационная транзакция-manager = "transactionManager"/>>
Это делает его яснее. В реальных проектах методы XML и аннотации также являются наиболее часто используемыми сценариями.
беременный Тестовый случай
Он точно такой же, как третий тестовый пример, и результат выходного вывода одинаково, и он не имеет напрямую.
В приведенном выше говорится о четырех способах использования вещей весной. Среди них метод жесткого кода может быть лучшим пониманием, что эквивалентно непосредственному переводу метода использования вещей в SQL в соответствующий код Java; и метод фабрики эквивалентен лечению особых ситуаций и обработки каждой вещи с помощью прокси -класса для повышения функции вещей; Последние два принципа практически реализованы с использованием уведомления о вещах (AOP) для определения тангенсных точек и связанной информации.
Программирование:
transactionTemplate#executeProxy BeanFactory:
Конфигурация XML:
Метод аннотации:
tx:annotation-driven transaction-manager="transactionManager"/>документ
Четыре способа управления весенними транзакциями
Исходный код
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.