У меня есть последние версии mysql, Hikari, весенняя загрузка 2 в мультитенантном приложении, с использованием программного источника данных, установленного программно.
Я могу читать записи таблицы в базах данных (mysql), но не могуобновить или вставить или изменить.
В основном следующее 'вера ведет к постановке в очередь запросов на сохранение
===========
j.i.AbstractLogicalConnectionImplementor : Preparing to begin transaction via JDBC Connection.setAutoCommit(false)
2019-09-25 10:05:20.758 TRACE 2643 --- [nio-8080-exec-1] j.i.AbstractLogicalConnectionImplementor : Transaction begun via JDBC Connection.setAutoCommit(false)
=========
, что приводит к постановке в очередь вставки
======== EntityIdentityInsertAction для объекта [com.xx.xx.xx.user]
2019-09-25 10:05:20.761 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.engine.spi.ActionQueue : Adding insert with no non-nullable, transient entities: [EntityIdentityInsertAction[com.xx.xx.user#<delayed:2>]]
========
Как настроить базовое соединение JDBC на автоматическую фиксацию?
Чего мне не хватает?Заранее спасибо
Пробовал:
repo.saveAndFlush () и repo.flush () - оба дают мне исключение, что транзакция не выполняется
сериализовали объект / табличную сущность
установили ds.setAutoCommit (true);ds.setReadOnly (ложь);// ds - источник данных
В application.properties установлено значение spring.datasource.hikari.auto-commit = true
===== Дамп конфигурации пула Hikari показывает, что автоматическая фиксация верна ===
2019-09-25 10:05:20.795 DEBUG 2643 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariConfig : allowPoolSuspension.............false
2019-09-25 10:05:20.795 DEBUG 2643 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariConfig : autoCommit......................true
======== конец дампа конфигурации Hikari ====
Но JDBCТрассировка показывает, что auotcommit имеет значение false при вызове repo.save (пользователь)
019-09-25 10:05:20.758 DEBUG 2643 --- [nio-8080-exec-1] o.h.e.t.internal.TransactionImpl : begin
2019-09-25 10:05:20.758 TRACE 2643 --- [nio-8080-exec-1] j.i.AbstractLogicalConnectionImplementor : Preparing to begin transaction via JDBC Connection.setAutoCommit(false)
2019-09-25 10:05:20.758 TRACE 2643 --- [nio-8080-exec-1] j.i.AbstractLogicalConnectionImplementor : Transaction begun via JDBC Connection.setAutoCommit(false)
2019-09-25 10:05:20.759 TRACE 2643 --- [nio-8080-exec-1] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#afterBeginCallback
2019-09-25 10:05:20.759 TRACE 2643 --- [nio-8080-exec-1] .i.SessionFactoryImpl$SessionBuilderImpl : Opening Hibernate Session. tenant=1, owner=null
2019-09-25 10:05:20.759 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : Opened Session [c0c25dff-2c0a-4996-b352-1ac4d49e48e8] at timestamp: 1569423920759
2019-09-25 10:05:20.760 TRACE 2643 --- [nio-8080-exec-1] o.hibernate.engine.spi.IdentifierValue : ID unsaved-value: 0
2019-09-25 10:05:20.760 TRACE 2643 --- [nio-8080-exec-1] o.h.e.i.AbstractSaveEventListener : Transient instance of: com.xx.xx.xx.user
2019-09-25 10:05:20.760 TRACE 2643 --- [nio-8080-exec-1] o.h.e.i.DefaultPersistEventListener : Saving transient instance
2019-09-25 10:05:20.760 TRACE 2643 --- [nio-8080-exec-1] o.h.e.i.AbstractSaveEventListener : Saving [com.xx.xx.xx.user#<null>]
2019-09-25 10:05:20.760 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.engine.spi.ActionQueue : Adding an EntityIdentityInsertAction for [com.xx.xx.xx.user] object
2019-09-25 10:05:20.761 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.engine.spi.ActionQueue : Adding insert with no non-nullable, transient entities: [EntityIdentityInsertAction[com.xx.xx.user#<delayed:2>]]
2019-09-25 10:05:20.761 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.engine.spi.ActionQueue : Adding resolved non-early insert action
2019-09-25 10:05:20.761 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : Closing session [c0c25dff-2c0a-4996-b352-1ac4d49e48e8]
2019-09-25 10:05:20.761 TRACE 2643 --- [nio-8080-exec-1] o.h.e.jdbc.internal.JdbcCoordinatorImpl : Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl@3cba167b]
2019-09-25 10:05:20.761 TRACE 2643 --- [nio-8080-exec-1] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] o.h.r.j.i.LogicalConnectionManagedImpl : Closing logical connection
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] o.h.r.j.i.LogicalConnectionManagedImpl : Logical connection closed
2019-09-25 10:05:20.762 DEBUG 2643 --- [nio-8080-exec-1] o.h.e.t.internal.TransactionImpl : committing
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] cResourceLocalTransactionCoordinatorImpl : ResourceLocalTransactionCoordinatorImpl#beforeCompletionCallback
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : SessionImpl#beforeTransactionCompletion()
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] org.hibernate.internal.SessionImpl : Automatically flushing session
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] .t.i.SynchronizationRegistryStandardImpl : SynchronizationRegistryStandardImpl.notifySynchronizationsBeforeTransactionCompletion
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] j.i.AbstractLogicalConnectionImplementor : Preparing to commit transaction via JDBC Connection.commit()
2019-09-25 10:05:20.762 TRACE 2643 --- [nio-8080-exec-1] j.i.AbstractLogicalConnectionImplementor : Transaction committed via JDBC Connection.commit()
2019-09-25 10:05:20.763 TRACE 2643 --- [nio-8080-exec-1] j.i.AbstractLogicalConnectionImplementor : re-enabling auto-commit on JDBC Connection after completion of JDBC-based transaction
2019-09-25 10:05:20.763 TRACE 2643 --- [nio-8080-exec-1] j.i.AbstractLogicalConnectionImplementor : LogicalConnection#afterTransaction
2019-09-25 10:05:20.763 TRACE 2643 --- [nio-8080-exec-1] o.h.r.j.i.ResourceRegistryStandardImpl : Releasing JDBC resources
======================== Repo is
@ Открытый интерфейс репозитория UserRepository расширяет JpaRepository {}
======== Сущность
@Persistent
@Entity
@Table(name = "user")
public class User implements Serializable {
// private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "username")
private String username;
===Rest of fields with setters and getters==
@Override
public String toString() {
return "User [id=" + this.id + ", username=" + this.username +", email="+ this.email+ "
+ "]";
}
}
класс обслуживания
@Service
@Persistent
@Transactional(transactionManager="tenantTransactionManager")
public class UserService {
@Autowired
private UserRepository repo;
public List<User> listAll() {
return repo.findAll();
}
public void save(User user) {
try {
repo.save(user);
}catch(Exception e) {
e.printStackTrace();
}
}
public User get(long id) { return repo.findById(id).get();}
public void delete(long id) { repo.deleteById(id); }
}
======= tenantManager ===
@ Bean (name = "tenantEntityManagerFactory") @ConditionalOnBean (name = "datasourceBasedMultitenantConnectionProvider")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
) {
//cleaned up on code not directly related
LocalContainerEntityManagerFactoryBean emfBean = new LocalContainerEntityManagerFactoryBean();
emfBean.setPackagesToScan(
new String[] { User.class.getPackage().getName(),
UserRepository.class.getPackage().getName(),
UserService.class.getPackage().getName() });
emfBean.setJpaVendorAdapter(jpaVendorAdapter());
Map<String, Object> properties = new HashMap<>();
properties.put(org.hibernate.cfg.Environment.MULTI_TENANT,
MultiTenancyStrategy.SCHEMA);
properties.put(
org.hibernate.cfg.Environment.MULTI_TENANT_CONNECTION_PROVIDER, connectionProvider);
properties.put(
org.hibernate.cfg.Environment.MULTI_TENANT_IDENTIFIER_RESOLVER,
tenantResolver);
properties.put(org.hibernate.cfg.Environment.DIALECT,
"org.hibernate.dialect.MySQL5Dialect");
properties.put(org.hibernate.cfg.Environment.SHOW_SQL, true);
properties.put(org.hibernate.cfg.Environment.FORMAT_SQL, true);
properties.put("hibernate.id.new_generator_mappings", "false");
properties.put("spring.jpa.hibernate.ddl-auto", "none");
properties.put("spring.jpa.hibernate.autocommit", "true");
properties.put("spring.datasource.hikari.auto-commit", "true");
properties.put("hibernate.connection.autocommit", "true");
emfBean.setJpaPropertyMap(properties);
return emfBean;
}
} ===== и поставщик источника данных ===
открытый статический источник данных createAndConfigureDataSource ({
//=======================
HikariDataSource ds = new HikariDataSource();
ds.setUsername(xxx);
ds.setPassword(xxx);
ds.setJdbcUrl(xxxx);
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setConnectionTimeout(20000);
// Minimum number of idle connections in the pool
ds.setMinimumIdle(10);
ds.setMaximumPoolSize(20);
ds.setIdleTimeout(300000);
ds.setConnectionTimeout(20000);
ds.setAutoCommit(true);
ds.setReadOnly(false);
return ds;
}}
application.properties ====
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
logging.level.org.springframework=WARN
logging.level.com=TRACE
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.type=TRACE
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=TRACE
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
logging.level.org.springframework.jdbc.core.JdbcTemplate=TRACE
logging.level.org.springframework.jdbc.core.StatementCreatorUtils=TRACE
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
logging.level.org.hibernate=TRACE
logging.level.org.hibernate.type=TRACE
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.hibernate.ddl-auto=none
spring.datasource.hikari.auto-commit =true
spring.jpa.hibernate.connection.autoCommit=true
=====
@Bean(name = "tenantTransactionManager")
public JpaTransactionManager transactionManager(
EntityManagerFactory tenantEntityManager) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(tenantEntityManager);
return transactionManager;
}