Если D - производный класс базового класса B, то вы можете назначить объект типа Derived переменной (или параметру) типа Base.
ПРИМЕР
class Pet
{
public:
string name;
};
class Dog : public Pet
{
public:
string breed;
};
int main()
{
Dog dog;
Pet pet;
dog.name = "Tommy";
dog.breed = "Kangal Dog";
pet = dog;
cout << pet.breed; //ERROR
Хотя указанное назначение разрешено, значение, присвоенное переменной pet, теряет поле породы. Это называется проблемой нарезки.
2. КАК ИЗМЕНИТЬ ПРОБЛЕМУ СЦЕПЛЕНИЯ
Чтобы устранить проблему, мы используем указатели на динамические переменные.
ПРИМЕР
Pet *ptrP;
Dog *ptrD;
ptrD = new Dog;
ptrD->name = "Tommy";
ptrD->breed = "Kangal Dog";
ptrP = ptrD;
cout << ((Dog *)ptrP)->breed;
В этом случае ни один из элементов данных или функций-членов динамической переменной, на которые указывает ptrD (объект класса потомка), будет потерян. Кроме того, если вам нужно использовать функции, функция должна быть виртуальной.
Транзакция A не завершится неудачей . Он не увидит данные, вставленные транзакцией B .
Демонстрация:
create table accounts (id bigserial primary key, balance bigint);
insert into accounts(balance) values (50), (100), (200);
Транзакция A :
begin transaction isolation level repeatable read;
select * from accounts where balance >= 100;
id | balance
----+---------
2 | 100
3 | 200
(2 rows)
Транзакция B :
begin;
insert into accounts(balance) values (300);
INSERT 0 1
commit;
Транзакция A :
select * from accounts where balance >= 100;
id | balance
----+---------
2 | 100
3 | 200
(2 rows)
Нет (4, 300)
строки.
(протестировано на PostgreSQL 11.2)
Обратите внимание, что PostgreSQL имеет более строгие гарантии на REPEATABLE READ
уровне изоляции. Это предотвращает фантомное чтение .
Уровень изоляции повторяемого чтения только видит данные, зафиксированные до начала транзакции; он никогда не видит ни незафиксированные данные, ни изменения, зафиксированные во время выполнения транзакций параллельными транзакциями (Тем не менее, запрос видит результаты предыдущих обновлений, выполненных в его собственной транзакции, даже если они еще не зафиксированы.) Это более надежная гарантия, чем требуется стандартом SQL для этого уровня изоляции [ 1132] blockquote>
Из таблицы 13.1. Уровни изоляции транзакции :
Фантомное чтение разрешено , разрешено на
REPEATABLE READ
уровне изоляции , но не в PGСм. Также :
Обновление
Если утверждение [ 1137]
update accounts set balance = balance + 30 where balance >= 100;
выдается как последний оператор транзакции A будут обновлены только 2 строки, потому что с точки зрения транзакции A есть только две строки, удовлетворяющие предикат
balance >= 100
:update accounts set balance = balance + 30 where balance >= 100; UPDATE 2
После фиксации:
commit; COMMIT select * from accounts; id | balance ----+--------- 1 | 50 4 | 300 2 | 130 3 | 230 (4 rows)
Обновляются только строки, возвращаемые этим оператором
select * from accounts where balance >= 100;
(исключая вставленную строку по транзакции B )
Обратите внимание, что транзакция A завершится с ошибкой , если попытается
update
изменить строку с помощью другой зафиксированной параллельной транзакции:A
begin transaction isolation level repeatable read; BEGIN select * from accounts where id = 1; id | balance ----+--------- 1 | 50 (1 row)
B
begin; BEGIN update accounts set balance = balance + 10; UPDATE 3 commit;
A :
[ 1110]Ошибка ожидается. Из документации:
Если первый апдейтер откатывается, то его эффекты отменяются, и повторяемая транзакция чтения может продолжить обновление первоначально найденной строки. Но если первый модуль обновления фиксирует (и фактически обновил или удалил строку, а не просто заблокировал ее), то повторяемая транзакция чтения будет откатываться с сообщением
blockquote>
ERROR: could not serialize access due to concurrent update
потому что повторяемая транзакция чтения не может изменять или блокировать строки, измененные другими транзакциями после начала повторяемой транзакции чтения.Ожидается, что приложения будут повторять неудачные транзакции:
Когда приложение получает это сообщение об ошибке, оно должно прервать текущую транзакцию и повторить всю транзакцию с самого начала. [ 1150] BLOCKQUOTE>