Гистограмма сработала бы здесь, но я думаю, что проще вычислить ее самостоятельно и использовать гистограмму - учитывая, что вам также приходится иметь дело с Assets
.
Идея состоит в том, что вам нужно определить, к какой ячейке принадлежит каждая точка данных. Затем вы можете сгруппировать по бин и среднее значение, чтобы рассчитать среднее значение Assets
. На самом деле Seaborn справляется с этим довольно хорошо:
df['bins'] = pd.cut(df['Percentage'], bins=bins)
df['count'] = 1
fig, ax1 = plt.subplots()
sns.barplot(data=df, x='bins', y='count', estimator=np.sum, ax=ax1)
ax2 = ax1.twinx()
sns.pointplot(data=df, x='bins', y='Assets', color='m', join=False, ci=None, ax=ax2)
Я помню, что Мартин Фаулер советует сохранять контроль над транзакцией на бизнес-уровне, потому что транзакция является бизнес-проблемой. (Если вы разрабатываете класс BankAccount, транзакция является частью языка домена).
Вы можете попробовать реализовать TransactionScope, как в .NET, он работает примерно так
using (TransactionScope ts = new TransactionScope())
{
...
}
Это то же самое, что и (не совсем, но если вы - парень по Java, это более понятно для вас)
TransactionScope scope = new TransactionScope();
try
{
...
scope.Commit();
}
catch(Exception ex)
{
scope.Rollback();
throw;
}
Чтобы отделить бизнес-уровень от любых технологий DAO, вы можете добавить TransactionFactory на языке вашего домена, который возвращает ITransactionScope (интерфейс), который вы определили с помощью Commit и Методы отката. Таким образом, уровень вашего домена не привязан к уровню DAO, а только конкретная реализация TransactionFactory.
ITransactionScope scope = transactionFactory.CreateTransaction();
try
{
...
scope.Commit();
}
catch(Exception ex)
{
scope.Rollback();
throw;
}
Ваше право на то, что приложение является хорошим местом для объединения транзакций, поскольку позволяет составлять более сложные действия, выполняемые различными службами / менеджерами / или как вы хотите их называть.
Легко Решение состоит в том, чтобы определить интерфейс ITransaction и использовать какой-либо тип фабрики или DI, чтобы скрыть фактического разработчика ITransaction от вашего приложения. Я катал свой собственный в .net, используя nHibernate, и, по сути, у меня есть базовый класс, который используют все мои менеджеры (в этом случае менеджер содержит бизнес-логику для логического набора сущностей, таких как Membership, Order, которые могут использовать одно или несколько хранилищ). В моем базовом классе есть ITransaction BeginTransaction (), который динамически создает тип на основе файла конфигурации.
Затем этот класс работает с сеансом nHibernate для начала и принятия транзакций.
В прошлом я помещал логику транзакций в корневой DAO для иерархии DAO, которые соответствуют иерархии Объектов в вашей модели, которые представляют единый твердый объект в системе.
Т.е., если у вас есть и X, у которого много Y, и вы хотите хранить и извлекать X и их Y одновременно как один составной объект, то ваш DAO для X должен также вызвать DAO для Y. Затем вы может поместить транзакцию вокруг всего в ваших методах add () и update () в DAO для X - и даже сделать пакет Y DAO частным, чтобы скрыть его от основной бизнес-логики. Т.е. вместо бизнес-логики:
XDAO xDAO = new XDAO(conn);
xDAO.startTransaction();
boolean success = xDAO.add(x);
if (success)
for (Y y : x.getYs()) {
success = YDAO.add(y);
if (!success) break;
}
if (success)
xDAO.commit();
else
xDAO.rollback();
Вы бы просто имели:
XDAO xDAO = new XDAO(conn);
xDAO.add(x);
(с логикой успеха / фиксации / отката, внутренней по отношению к этому DAO)
Однако это не охватывает каждую ситуацию, и ваша может отличаться ( например, мой работает с JDBC, я не знаю, как работает Hibernate или там, где это возможно).
В веб-приложении для разграничения транзакций я использую преимущества цикла HTTP-запроса / ответа, где каждая атомарная бизнес-операция выполняется в рамках одного из этих циклов, в единственный выделенный поток.
Какой бы сетевой фреймворк ни использовался (Struts, JSF, GWT и т. д.), обычно существует «шов», где может быть выполнено разграничение транзакций. В Struts это может быть базовый класс Action. В GWT это может быть базовый класс RemoteServiceImpl.
Итак, используйте эту центральную точку доступа, чтобы открыть транзакцию (прежде чем разрешить выполнение кода конкретного приложения) и завершить ее фиксацией, если не появилось никаких исключений. или откат в противном случае (после того, как код конкретного приложения был выполнен).
Я широко применил эту стратегию в большом и сложном бизнес-веб-приложении,